// UIImage+Resize.m
// Created by Trevor Harmon on 8/5/09.
// Free for personal or commercial use, with or without modification.
// No warranty is expressed or implied.

#import "UIImage+Resize.h"
#import "UIImage+RoundedCorner.h"
#import "UIImage+Alpha.h"

@implementation UIImage (Resize)

// Returns a copy of this image that is cropped to the given bounds.
// The bounds will be adjusted using CGRectIntegral.
// This method ignores the image's imageOrientation setting.
- (UIImage *)croppedImage:(CGRect)bounds {
    CGRect croppedRect  = CGRectMake(bounds.origin.x*self.scale,
                                     bounds.origin.y*self.scale,
                                     bounds.size.width*self.scale,
                                     bounds.size.height*self.scale);
    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], croppedRect);
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef scale:self.scale*self.scale orientation:self.imageOrientation];
    CGImageRelease(imageRef);
    return croppedImage;
}

// Returns a copy of this image that is squared to the thumbnail size.
// If transparentBorder is non-zero, a transparent border of the given size will be added around the edges of the thumbnail. (Adding a transparent border of at least one pixel in size has the side-effect of antialiasing the edges of the image when rotating it using Core Animation.)
- (UIImage *)thumbnailImage:(NSInteger)thumbnailSize
          transparentBorder:(NSUInteger)borderSize
               cornerRadius:(NSUInteger)cornerRadius
       interpolationQuality:(CGInterpolationQuality)quality {
    UIImage *resizedImage = [self resizedImageWithContentMode:UIViewContentModeScaleAspectFill
                                                       bounds:CGSizeMake(thumbnailSize, thumbnailSize)
                                         interpolationQuality:quality];
    
    // Crop out any part of the image that's larger than the thumbnail size
    // The cropped rect must be centered on the resized image
    // Round the origin points so that the size isn't altered when CGRectIntegral is later invoked
    CGRect cropRect = CGRectMake(round((resizedImage.size.width - thumbnailSize) / 2),
                                 round((resizedImage.size.height - thumbnailSize) / 2),
                                 thumbnailSize,
                                 thumbnailSize);
    UIImage *croppedImage = [resizedImage croppedImage:cropRect];
    
    UIImage *transparentBorderImage = borderSize ? [croppedImage transparentBorderImage:borderSize] : croppedImage;
    
    return [transparentBorderImage roundedCornerImage:cornerRadius borderSize:borderSize];
}

// Returns a rescaled copy of the image, taking into account its orientation
// The image will be scaled disproportionately if necessary to fit the bounds specified by the parameter
- (UIImage *)resizedImage:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)quality {
    BOOL drawTransposed;
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    // In iOS 5 the image is already correctly rotated. See Eran Sandler's
    // addition here: http://eran.sandler.co.il/2011/11/07/uiimage-in-ios-5-orientation-and-resize/
    
    if ( [[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0 ) 
    {
        drawTransposed = NO;  
    } 
    else 
    {    
        switch ( self.imageOrientation ) 
        {
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                drawTransposed = YES;
                break;
            default:
                drawTransposed = NO;
        }
        
        transform = [self transformForOrientation:newSize];
    } 
    
    return [self resizedImage:newSize transform:transform drawTransposed:drawTransposed interpolationQuality:quality];
}

// Resizes the image according to the given content mode, taking into account the image's orientation
- (UIImage *)resizedImageWithContentMode:(UIViewContentMode)contentMode
                                  bounds:(CGSize)bounds
                    interpolationQuality:(CGInterpolationQuality)quality {
    CGFloat horizontalRatio = bounds.width / self.size.width;
    CGFloat verticalRatio = bounds.height / self.size.height;
    CGFloat ratio;
    
    switch (contentMode) {
        case UIViewContentModeScaleAspectFill:
            ratio = MAX(horizontalRatio, verticalRatio);
            break;
            
        case UIViewContentModeScaleAspectFit:
            ratio = MIN(horizontalRatio, verticalRatio);
            break;
            
        default:
            [NSException raise:NSInvalidArgumentException format:@"Unsupported content mode: %d", contentMode];
    }
    
    CGSize newSize = CGSizeMake(self.size.width * ratio, self.size.height * ratio);
    
    return [self resizedImage:newSize interpolationQuality:quality];
}

#pragma mark -
#pragma mark Private helper methods

// Returns a copy of the image that has been transformed using the given affine transform and scaled to the new size
// The new image's orientation will be UIImageOrientationUp, regardless of the current image's orientation
// If the new size is not integral, it will be rounded up
- (UIImage *)resizedImage:(CGSize)newSize
                transform:(CGAffineTransform)transform
           drawTransposed:(BOOL)transpose
     interpolationQuality:(CGInterpolationQuality)quality {
    CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
    CGRect transposedRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width);
    CGImageRef imageRef = self.CGImage;
    
    // Fix for a colorspace / transparency issue that affects some types of 
    // images. See here: http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/comment-page-2/#comment-39951
        
    CGContextRef bitmap =CGBitmapContextCreate( NULL,
                                               newRect.size.width,
                                               newRect.size.height,
                                               8,
                                               0,
                                               CGImageGetColorSpace( imageRef ),
                                               kCGImageAlphaNoneSkipLast );
    
    // Rotate and/or flip the image if required by its orientation
    CGContextConcatCTM(bitmap, transform);
    
    // Set the quality level to use when rescaling
    CGContextSetInterpolationQuality(bitmap, quality);
    
    // Draw into the context; this scales the image
    CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef);
    
    // Get the resized image from the context and a UIImage
    CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
    
    // Clean up
    CGContextRelease(bitmap);
    CGImageRelease(newImageRef);
    
    return newImage;
}

// Returns an affine transform that takes into account the image orientation when drawing a scaled image
- (CGAffineTransform)transformForOrientation:(CGSize)newSize {
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    switch (self.imageOrientation) {
        case UIImageOrientationDown:           // EXIF = 3
        case UIImageOrientationDownMirrored:   // EXIF = 4
            transform = CGAffineTransformTranslate(transform, newSize.width, newSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;
            
        case UIImageOrientationLeft:           // EXIF = 6
        case UIImageOrientationLeftMirrored:   // EXIF = 5
            transform = CGAffineTransformTranslate(transform, newSize.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;
            
        case UIImageOrientationRight:          // EXIF = 8
        case UIImageOrientationRightMirrored:  // EXIF = 7
            transform = CGAffineTransformTranslate(transform, 0, newSize.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }
    
    switch (self.imageOrientation) {
        case UIImageOrientationUpMirrored:     // EXIF = 2
        case UIImageOrientationDownMirrored:   // EXIF = 4
            transform = CGAffineTransformTranslate(transform, newSize.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
            
        case UIImageOrientationLeftMirrored:   // EXIF = 5
        case UIImageOrientationRightMirrored:  // EXIF = 7
            transform = CGAffineTransformTranslate(transform, newSize.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        default:
            break;
    }
    
    return transform;
}
-(UIImage*) cropSubImageToRect:(CGRect) subRectInOrigin
{
    //    CGSize subImageSize = CGSizeMake(subRectInOrigin.size.width, subRectInOrigin.size.height);
    //    //定义裁剪的区域相对于原图片的位置
    //    CGRect subImageRect = subImageRect;
    //    CGImageRef imageRef = self.CGImage;
    //    CGImageRef subImageRef = CGImageCreateWithImageInRect(imageRef, subImageRect);
    //    UIGraphicsBeginImageContext(subImageSize);
    //    CGContextRef context = UIGraphicsGetCurrentContext();
    //    CGContextDrawImage(context, subImageRect, subImageRef);
    //    UIImage* subImage = [UIImage imageWithCGImage:subImageRef];
    //    UIGraphicsEndImageContext();
    //    //返回裁剪的部分图像
    //    return subImage;
    CGImageRef imgRef = self.CGImage;
    CGImageRef img= CGImageCreateWithImageInRect(imgRef,subRectInOrigin);
    UIImage* ret = nil;
    if (img)
    {
        ret = [UIImage imageWithCGImage:img];
        CFRelease(img);
    }
    return ret;
}
+ (UIImage *)imageSmartNamed:(NSString *)name
{
    CGRect bounds = [[UIScreen mainScreen] bounds];
    // 有无后缀
    NSString* extension = [name pathExtension];
    if ([extension length] == 0) {
        extension = @"png";
    }
    
    // 有无@2x
    NSString* scale = @"";
    NSString* path = [name stringByDeletingPathExtension];
    NSRange rangeOf2x = [path rangeOfString:@"@2x"];
    if (rangeOf2x.location == NSNotFound) {
        scale = @"@2x";
    }
    if (bounds.size.height == 568 || bounds.size.height == 1136) {
        // 有无-568h
        NSString* h568 = @"";
        NSRange rangeOf568h =[path rangeOfString:@"-568h"];
        if (rangeOf568h.location == NSNotFound) {
            h568 = @"-568h";
        }
        return [UIImage imageNamed:[NSString stringWithFormat:@"%@%@%@.%@", path, h568, scale, extension]];
    }else if(bounds.size.height == 667 || bounds.size.height == 1334){
        // 有无-667h
        NSString* h667 = @"";
        NSRange rangeOf667h =[path rangeOfString:@"-667h"];
        if (rangeOf667h.location == NSNotFound) {
            h667 = @"-667h";
        }
        return [UIImage imageNamed:[NSString stringWithFormat:@"%@%@%@.%@", path, h667, scale, extension]];

    }else if(bounds.size.height > 1334){
        // 有无@2x
        NSString* scale = @"";
        NSString* path = [name stringByDeletingPathExtension];
        NSRange rangeOf3x = [path rangeOfString:@"@3x"];
        if (rangeOf3x.location == NSNotFound) {
            scale = @"@3x";
        }
        // 有无-736h
        NSString* h736 = @"";
        NSRange rangeOf736h =[path rangeOfString:@"-736h"];
        if (rangeOf736h.location == NSNotFound) {
            h736 = @"-736h";
        }
        return [UIImage imageNamed:[NSString stringWithFormat:@"%@%@%@.%@", path, h736, scale, extension]];
    }
    return [UIImage imageNamed:name];
}
@end
